from fastapi import FastAPI, Depends, HTTPException, Query
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import StreamingResponse
from sqlalchemy.orm import Session
import json
from typing import List

from database import get_db, create_tables
from models import Conversation, Message
from schemas import (
    ChatRequest, ChatResponse, ConversationList,
    ConversationDetail, FeedbackRequest, RecommendedQuestions, MessageDetail, BaseResponse, PaginationResponse
)
from llm_service import llm_service

app = FastAPI(title="AI对话系统", version="1.0.0")

# CORS配置
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


# 创建数据库表 - 使用同步启动事件
@app.on_event("startup")
def startup_event():
    create_tables()


@app.get("/")
async def root():
    return BaseResponse(
        code=200,
        msg="AI对话系统API",
        data=""
    )


@app.post("/conversations/chat", response_model=ChatResponse)
async def chat_stream(request: ChatRequest, db: Session = Depends(get_db)):
    """流式对话接口"""
    # 生成或获取会话ID
    if not request.session_id:
        return BaseResponse(
            code=500,
            msg="会话不存在",
            data=None
        )
    else:
        session_id = request.session_id
        conversation = db.query(Conversation).filter(Conversation.session_id == session_id).first()
        if not conversation:
            # 创建新会话
            conversation = Conversation(session_id=session_id, title=request.message[:50] + "..." if len(request.message) > 50 else request.message)
            db.add(conversation)
            db.commit()
            db.refresh(conversation)
        # else:
    #         存在则更新会话标题
            # conversation.title = request.message[:50] + "..." if len(request.message) > 50 else request.message
            # db.commit()

    # 保存用户消息
    user_message = Message(
        conversation_id=conversation.id,
        content=request.message,
        is_user=True
    )
    db.add(user_message)
    db.commit()
    db.refresh(user_message)

    # 构建对话历史
    history_messages = db.query(Message).filter(
        Message.conversation_id == conversation.id
    ).order_by(Message.created_at).all()

    messages_for_llm = []
    for msg in history_messages:
        role = "user" if msg.is_user else "assistant"
        messages_for_llm.append({"role": role, "content": msg.content})

    # 添加系统提示
    system_prompt = {"role": "system", "content": "你是一个有帮助的AI助手。"}
    messages_for_llm.insert(0, system_prompt)

    async def generate_response():
        full_response = ""
        async for chunk in llm_service.stream_chat(messages_for_llm):
            full_response += chunk
            yield f"data: {json.dumps({'message': chunk, 'is_finished': False}, ensure_ascii=False)}\n\n"

        # 保存AI回复
        ai_message = Message(
            conversation_id=conversation.id,
            content=full_response,
            is_user=False
        )
        db.add(ai_message)
        db.commit()

        # 更新会话标题（如果是新会话）
        if not conversation.title:
            # 使用用户的第一条消息作为标题
            conversation.title = request.message[:50] + "..." if len(request.message) > 50 else request.message
            db.commit()

        yield f"data: {json.dumps({'message': '', 'is_finished': True})}\n\n"

    return StreamingResponse(
        generate_response(),
        media_type="text/event-stream",
        headers={
            "Cache-Control": "no-cache",
            "Connection": "keep-alive",
        }
    )


@app.get("/conversations/list", response_model=PaginationResponse[ConversationList])
async def get_conversations(
    page: int = Query(1, description="页码"),
    page_size: int = Query(10, description="每页数量"),
    db: Session = Depends(get_db)
):
    """获取对话列表"""
    # 计算偏移量
    offset = (page - 1) * page_size

    # 获取总数
    total = db.query(Conversation).count()
    # 获取分页数据
    conversations = db.query(Conversation).order_by(Conversation.updated_at.desc()).offset(offset).limit(page_size).all()

    result = []
    for conv in conversations:
        message_count = db.query(Message).filter(Message.conversation_id == conv.id).count()
        result.append(ConversationList(
            id=conv.id,
            session_id=conv.session_id,
            title=conv.title,
            created_at=conv.created_at,
            message_count=message_count
        ))

        # 计算总页数
    total_pages = (total + page_size - 1) // page_size

    return PaginationResponse(
        code=200,
        msg="获取对话列表成功",
        data=result,
        total=total,
        page=page,
        page_size=page_size,
        total_pages=total_pages
    )


@app.get("/conversations/detail", response_model=BaseResponse)
async def get_conversation_detail(session_id: str = Query(..., description="会话ID"), db: Session = Depends(get_db)):
    """获取对话详情"""
    conversation = db.query(Conversation).filter(Conversation.session_id == session_id).first()
    if not conversation:
        return BaseResponse(
            code=500,
            msg="会话不存在",
            data=None
        )

    messages = db.query(Message).filter(
        Message.conversation_id == conversation.id
    ).order_by(Message.created_at).all()

    message_details = []
    for msg in messages:
        message_details.append(MessageDetail(
            id=msg.id,
            content=msg.content,
            is_user=msg.is_user,
            is_positive=msg.is_positive,
            feedback_content=msg.feedback_content,
            created_at=msg.created_at
        ))

    return BaseResponse(
        code=200,
        msg="获取对话详情成功",
        data=ConversationDetail(
            id=conversation.id,
            session_id=conversation.session_id,
            title=conversation.title,
            created_at=conversation.created_at,
            messages=message_details
        )
    )


@app.get("/conversations/delete")
async def delete_conversation(session_id: str= Query(..., description="会话ID"), db: Session = Depends(get_db)):
    """删除对话"""
    conversation = db.query(Conversation).filter(Conversation.session_id == session_id).first()
    if not conversation:
        return BaseResponse(
            code=500,
            msg="会话不存在",
            data=None
        )

    db.query(Message).filter(Message.conversation_id == conversation.id).delete(synchronize_session=False)
    db.delete(conversation)
    db.commit()

    return BaseResponse(
        code=200,
        msg="对话删除成功",
        data=None
    )


@app.get("/conversations/recommend-questions", response_model=BaseResponse)
async def get_recommended_questions(db: Session = Depends(get_db)):
    """获取推荐问题"""
    # 查询数据库表Message最新的一条用户提问的数据
    latest_user_message = db.query(Message).filter(Message.is_user == True).order_by(Message.created_at.desc()).first()
    if not latest_user_message:
        return BaseResponse(
            code=404,
            msg="没有用户提问",
            data=None
        )

    questions = await llm_service.generate_questions(latest_user_message.content)
    return BaseResponse(
        code=200,
        msg="获取推荐问题成功",
        data=RecommendedQuestions(questions=questions)
    )


@app.post("/conversations/feedback")
async def submit_feedback(request: FeedbackRequest, db: Session = Depends(get_db)):
    """提交反馈"""
    message = db.query(Message).filter(Message.id == request.message_id).first()
    if not message:
        raise HTTPException(status_code=404, detail="消息不存在")
    # 更新现有反馈
    message.is_positive = request.is_positive
    message.feedback_content = request.feedback_content

    db.commit()
    return BaseResponse(
        code=200,
        msg="反馈提交成功",
        data=None
    )


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=8000)